package com.gurumades.jsonform.client.forms;

import java.util.Map;

import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.dispatch.client.ExceptionHandler;
import net.customware.gwt.dispatch.client.standard.StandardDispatchAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HasHandlers;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
import com.gurumades.jsonform.client.JSONUtils;
import com.gurumades.jsonform.shared.dispatch.GetUploadUrlAction;
import com.gurumades.jsonform.shared.dispatch.GetUploadUrlResult;

public class UploadPhoto extends Composite implements HasHandlers,
		FormItemViewIF {

	private static UploadPhotoUiBinder uiBinder = GWT
			.create(UploadPhotoUiBinder.class);

	DispatchAsync userImageService = new StandardDispatchAsync(
			new ExceptionHandler() {

				@Override
				public Status onFailure(Throwable e) {
					Window.alert("Dispatch of action failled :"
							+ e.getLocalizedMessage());

					return Status.STOP;
				}
			});

	private HandlerManager handlerManager;

	private JSONObject uploadedImage;

	interface UploadPhotoUiBinder extends UiBinder<Widget, UploadPhoto> {
	}

	@UiField
	Button uploadButton;

	@UiField
	FormPanel uploadForm;

	@UiField
	FileUpload uploadField;

	@UiField
	Image tmpImage;

	private JSONObject itemSettings;

	private Map<String, String> extras;

	public UploadPhoto() {
		handlerManager = new HandlerManager(this);

		initWidget(uiBinder.createAndBindUi(this));

		uploadButton.setText("Upload");
		uploadButton.setText("Loading...");
		uploadButton.setEnabled(false);

		uploadField.setName("image");

		startNewBlobstoreSession();

		uploadForm
				.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {

					@Override
					public void onSubmitComplete(SubmitCompleteEvent event) {
						uploadForm.reset();
						startNewBlobstoreSession();

						String json = event.getResults();

						try {
							JSONArray arr = (JSONArray) JSONParser
									.parseLenient(json);
							if (arr.size() > 0) {
								uploadedImage = arr.get(0).isObject();
								tmpImage.setUrl(uploadedImage.get("url")
										.isString().stringValue());
							}
						} catch (Exception e) {
							Window.alert("An error while uploading the files : "
									+ e.getLocalizedMessage());
						}

					}
				});
	}

	private void startNewBlobstoreSession() {

		AsyncCallback<GetUploadUrlResult> callback = new AsyncCallback<GetUploadUrlResult>() {

			@Override
			public void onSuccess(GetUploadUrlResult result) {
				uploadForm.setAction(result.getUploadURL());
				uploadForm.setEncoding(FormPanel.ENCODING_MULTIPART);
				uploadForm.setMethod(FormPanel.METHOD_POST);

				uploadButton.setText("Upload");
				uploadButton.setEnabled(true);

			}

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub

			}
		};

		userImageService.execute(new GetUploadUrlAction(), callback);
	}

	@UiHandler("uploadButton")
	void onSubmit(ClickEvent e) {
		uploadForm.submit();
	}

	@Override
	public void fireEvent(GwtEvent<?> event) {
		handlerManager.fireEvent(event);
	}

	@Override
	public void setData(JSONValue object) {

	}

	@Override
	public boolean isValueEmpty() {
		return uploadedImage == null;
	}

	@Override
	public JSONObject getValue() {
		return uploadedImage;
	}

	@Override
	public void initFormItem(JSONValue value, JSONObject formItemSettings) {
		this.itemSettings = formItemSettings;

		JSONObject extra = formItemSettings.get("extra").isObject();
		if (extra != null
				&& extra.get("extraKeyAndExtraValue").isArray() != null) {
			JSONArray arr = extra.get("extraKeyAndExtraValue").isArray();

			for (int i = 0; i < arr.size(); i = i + 2) {
				JSONObject key = arr.get(i).isObject().get("JAXBElement")
						.isObject();
				JSONObject val = arr.get(i + 1).isObject().get("JAXBElement")
						.isObject();
				extras.put(JSONUtils.getString("value", key),
						JSONUtils.getString("value", val));
			}

		}
	}

	@Override
	public void setError(boolean b, String string) {
		if (b) {
			removeStyleName("jsonForm-error");
			addStyleName("jsonForm-error");
		} else {
			removeStyleName("jsonForm-error");
		}

	}
}
